package command

import (
	"context"
	"encoding/json"
	"energy-amiot-platform/core"
	"energy-amiot-platform/model/dbspo"
	"energy-amiot-platform/model/redispo"
	"energy-amiot-platform/model/request"
	_ "energy-amiot-platform/model/response"
	"energy-amiot-platform/utils/respout"
	"errors"
	"fmt"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
)

var (
	moduleCode = 2
)

// @Tags 指令管理
// @Summary 向设备发送工作指令
// @Description 向设备发送工作指令
// @Accept  json
// @Product json
// @Param   input body request.CommandReqSwag  true		"工作参数指令数据"
// @Success 200 {object} response.Response "Ok"
// @Router /command/{id} [post]
func send(ctx *gin.Context) {
	sendCommand(ctx)
}

// @Tags 指令管理
// @Summary 向设备发送工作指令（客户）
// @Description 向设备发送工作指令（客户）
// @Accept  json
// @Product json
// @Param   input body request.CommandReqSwag  true		"工作参数指令数据"
// @Success 200 {object} response.Response "Ok"
// @Router /client/command/{id} [post]
func sendForClient(ctx *gin.Context) {
	sendCommand(ctx)
}

func sendCommand(ctx *gin.Context) {
	var handleCode = 1
	var req request.MiotCmdReq
	var iotCmdId = strings.Replace(uuid.New().String(), "-", "-", -1)
	var nodeId string
	var nodeKey string
	var cmdKey string
	var topic string
	var background = context.Background()

	nodeId = ctx.Param("id")
	if nodeId == "" {
		respout.SendError(ctx, core.APP.Code, moduleCode, handleCode, 0, respout.StrErrParse, errors.New("设备标识为空"), nil)
		return
	}

	//all, _ := io.ReadAll(ctx.Request.Body)
	//err := json.Unmarshal(all, &req)
	err := ctx.ShouldBindJSON(&req)
	if err != nil {
		respout.SendError(ctx, core.APP.Code, moduleCode, handleCode, 1, respout.StrErrParse, err, nil)
		return
	}

	pv, _ := ctx.Get("product")
	product := pv.(*dbspo.Product)

	nodeKey = "mqtt_user:" + nodeId
	cmdKey = "mqtt_cmd:" + nodeId + ":" + iotCmdId
	topic = fmt.Sprintf(core.TopicSetPattern, product.ID, nodeId)

	l, err := core.REDIS.HLen(background, nodeKey).Result()
	switch {
	case err != nil:
		respout.SendError(ctx, core.APP.Code, moduleCode, handleCode, 2, respout.StrFail, err, nil)
		return
	case l == 0:
		respout.SendError(ctx, core.APP.Code, moduleCode, handleCode, 3, respout.StrFail, errors.New("设备不存在"), nil)
		return
	}

	// 进一步解析（扩展在这里，按照指令的格式解析）
	now := time.Now()
	marshal, _ := json.Marshal(req)

	// 将指令缓存到推送队列
	core.MQTT.Client.Publish(topic, 0, false, marshal)
	cmdItem := redispo.CmdItemCache{
		CreateAt: now,
		Send:     false,
	}
	pipeline := core.REDIS.Pipeline()
	pipeline.HMSet(background, cmdKey, &cmdItem)
	pipeline.Expire(background, cmdKey, 7200)
	pipeline.Exec(background)

	result := CmdCreateResult{
		CmdId:     iotCmdId,
		CreatedAt: now.Unix(),
	}
	respout.Ok(ctx, result)
}

type CmdCreateResult struct {
	CmdId     string `json:"cmdId"`
	CreatedAt int64  `json:"createdAt"`
}
